package com.sxj.corejava.util;

import com.sxj.corejava.constant.DateConstant;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author 石小俊
 * 2024年07月22日 16:07
 */
public class DateUtil {

    /**
     * 将日期转换成指定格式的字符串
     * @param date    需要转换的日期
     * @param pattern 指定的格式
     * @return 转换后的字符串
     */
    public static String toString(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

    /**
     * 将日期转换成默认格式的字符串
     * @param date 需要转换的日期
     * @return 转换后的字符串
     * @see DateConstant
     */
    public static String toString(Date date) {
        return toString(date, DateConstant.DATE_DEFAULT_PATTERN);
    }

    /**
     * 将一个指定格式的字符串转换成日期
     * @param s       需要转换的字符串
     * @param pattern 字符串格式
     * @return 转换后的日期
     */
    public static Date toDate(String s, String pattern) throws ParseException {
        return new SimpleDateFormat(pattern).parse(s);
    }

    /**
     * 将一个默认格式的字符串转换成日期
     * @param s 需要转换的字符串
     * @return 转换后的日期
     * @see DateConstant
     */
    public static Date toDate(String s) throws ParseException {
        return toDate(s, DateConstant.DATE_DEFAULT_PATTERN);
    }

    /**
     * 计算指定日期的前一天
     * @param date 当天日期
     * @return 昨天
     */
    public static Date getYesterday(Date date) {
        return new Date(date.getTime() - DateConstant.ONE_DAY_MILLISECOND);
    }

    /**
     * 计算指定日期的后一天
     * @param date 当天日期
     * @return 明天
     */
    public static Date getTomorrow(Date date) {
        return new Date(date.getTime() + DateConstant.ONE_DAY_MILLISECOND);
    }

    /**
     * 计算两个日期之间相差的天数,不满一天的直接截取掉
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return
     */
    public static int getDuringDay(Date startDate, Date endDate) {
        long time = endDate.getTime() - startDate.getTime();
        // 不足一天的直接截取掉
        return (int) (time / DateConstant.ONE_DAY_MILLISECOND);
    }

    /**
     * 计算两个日期之间相差的天数,不满一天的算1天
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return
     */
    public static int getDuringDay2(Date startDate, Date endDate) {
        long time = endDate.getTime() - startDate.getTime();
        // 不足一天的直接截取掉
        if (time % DateConstant.ONE_DAY_MILLISECOND == 0) {
            return (int) (time / DateConstant.ONE_DAY_MILLISECOND);
        } else {
            return (int) (time / DateConstant.ONE_DAY_MILLISECOND) + 1;
        }
    }

    /**
     * 获取日期中指定的年、月、日、时、分、秒的值
     * 对应字段可以设置为常量
     * @param date  日期值
     * @param field 需要获取的字段是谁
     * @return 根据传递的参数不同, 返回日期中不同部分的值
     * @see DateConstant
     */
    public static int get(Date date, int field) {
        // 先将日期转换成字符串
        String s = toString(date, "yyyy-MM-dd HH:mm:ss");
        // 通过正则表达式将日期分割成数组
        // 日期的每一个部分作为数组的一个元素
        String[] arr = s.split("-|\\s|:");
        return Integer.parseInt(arr[field]);
    }

    /**
     * 根据指定的年份与月份,获取这一年这个月共有多少天
     * @param year
     * @param month
     * @return
     */
    public static int getDay(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        return calendar.getActualMaximum(Calendar.DATE);
    }

    /**
     * 根据指定的年份与月份,获取这一年这个月共有多少天
     * @param year
     * @param month
     * @return
     */
    public static int getDay2(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        // 想要知道这个月共有多少天
        // 可以将日历所表示的时间设置为这一年的这个月的最后一天
        // 但是由于已知条件只有年和月,无法直接设置天数
        // 这个月的最后一天的下一天是下个月的第一天
        // 我们可以设置下个月的第一天
        calendar.set(Calendar.YEAR, year);
        // 设置下一个月
        calendar.set(Calendar.MONTH, month - 1 + 1);
        // 设置第一天
        // calendar.set(Calendar.DATE,1);
        // 该日期的前一天即为这个月的最后一天
        calendar.set(Calendar.DATE, 0);
        //calendar.add(Calendar.DATE,-1);
        return calendar.get(Calendar.DATE);
    }
}
